package com.miyu.system.service.rule.impl;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.miyu.common.utils.aop.CacheBatchEvict;
import com.miyu.common.utils.commonUtils.Comutils;
import com.miyu.system.dao.system.SysRuleDao;
import com.miyu.common.pojo.system.SysRule;
import com.miyu.system.service.rule.SysRuleService;
import com.miyu.system.utils.enumeration.Result;
import com.miyu.system.utils.system.SystemUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * 系统规则服务实现
 * @author miyu
 * @date 2022/10/31
 */
@Service
public class SysRuleServiceImpl implements SysRuleService {

    @Resource
    private SysRuleDao sysRuleDao;
    /**
     * 查询系统规则
     * @param param 参数
     * @return {@link JSONArray}
     */
    @Override
    public JSONArray querySysRule(JSONObject param) {
        String ruleName ="ruleName";
        SysRule rule = new SysRule ();
        if(param.containsKey(ruleName) || StringUtils.isNotBlank(param.getString(ruleName))){
            rule.setRuleName(param.getString(ruleName));
        }
        ExampleMatcher matcher = ExampleMatcher.matching()
        .withMatcher(ruleName,match -> match.contains())
        .withIgnorePaths("isStop");
        Example<SysRule> example = Example.of(rule,matcher);
        List<SysRule> sysRuleList = sysRuleDao.findAll(example);
        JSONArray rs = JSONArray.of(sysRuleList).getJSONArray(0);
        return rs;
    }

    /**
     * 删除系统规则
     * @param params 参数
     * @return {@link JSONObject}
     */
    @Override
    @CacheBatchEvict(cacheNames="system:sysRule",key = "#params" ,type = "jsonArray",value = "ruleId")
    @CacheEvict(cacheNames="system:sysRule",key="'sysRule'")
    public JSONObject delSysRule(JSONArray params) {
        List<SysRule> sysRuleList = params.toJavaList(SysRule.class);
        //删除分表
        delTableModel(sysRuleList);
        sysRuleDao.deleteAllInBatch(sysRuleList);
        return Result.getInfoByCode("10001");
    }

    /**
     * 删除书籍分表
     * @param sysRuleList
     */
    private void delTableModel(List<SysRule> sysRuleList) {
        List<String> sqlList = new ArrayList<String>();
        for (SysRule sysRule : sysRuleList) {
            if(sysRule.getRuleType().equals("1")){
                String [] table = SystemUtils.createTable();
                StringBuffer sql = new StringBuffer();
                sql.append(" drop table book_main_").append(sysRule.getRuleId());
                sqlList.add(sql.toString());
                sql.setLength(0);
                for (int i = 0; i < table.length; i++) {
                    sql.append(" drop table book_chapter_").append(sysRule.getRuleId()).append("_").append(table[i]);
                    sqlList.add(sql.toString());
                    sql.setLength(0);
                    sql.append(" drop table book_reader_").append(sysRule.getRuleId()).append("_").append(table[i]);
                    sqlList.add(sql.toString());
                    sql.setLength(0);
                }
            }
        }
        if(sqlList.size()>0){
            sysRuleDao.doExecuteBatch(sqlList);
        }
    }

    /**
     * 编辑系统规则
     * @param param 参数
     * @return {@link SysRule}
     */
    @Override
    @Caching(evict={@CacheEvict(cacheNames = "system:sysRule" ,key="'sysRule'")})
    @CachePut(cacheNames = "system:sysRule" ,key="#result.getRuleId()")
    public SysRule editSysRule(JSONObject param) {
        SysRule rule = JSONObject.parseObject(param.toString(),SysRule.class);
        Boolean isCreate = false  ;
        /**获取uuid 主键使用*/
        String ruleId = Comutils.getUUID();

        if(StringUtils.isBlank(rule.getRuleId())){
            rule.setRuleId(ruleId);
            if("1".equals(rule.getRuleType())){
                isCreate = true;
            }
        }
        sysRuleDao.save(rule);
        //新增时增加分表功能
        if(isCreate){
            createTableModel(ruleId);
        }

        return rule;
    }

    /**
     * 创建分表储存数据不同类型创建不同分表
     * @param tableId 表id
     */
    private void createTableModel(String tableId) {
        //书籍表分三张表
        //1 书籍明细表
        creataTableMain(tableId);
        //2 书籍章节表
        createTableChapter(tableId);
        //3 书籍阅读表
        createTableReader(tableId);
    }

    /**
     * 书籍主表创建
     * @param tableId
     */
    private void creataTableMain(String tableId) {
        StringBuffer sql = new StringBuffer();
        sql.append("create table book_main_").append(tableId).append(" like book_main ");
        sysRuleDao.doExecute(sql.toString());
    }

    /**
     * 书籍章节表
     * @param tableId
     */
    private void createTableChapter(String tableId) {

        List<String> sqlList = new ArrayList<String>();
        String [] table = SystemUtils.createTable();
        for (int i = 0; i < table.length; i++) {
            StringBuffer sql = new StringBuffer();
            sql.append("create table book_chapter_").append(tableId).append("_").append(table[i]);
            sql.append(" like book_chapter ");
            sqlList.add(sql.toString());
        }
        sysRuleDao.doExecuteBatch(sqlList);
    }

    /**
     * 阅读内容表
     * @param tableId
     */
    private void createTableReader(String tableId) {
        List<String> sqlList = new ArrayList<String>();
        String [] table = SystemUtils.createTable();
        for (int i = 0; i < table.length; i++) {
            StringBuffer sql = new StringBuffer();
            sql.append("create table book_reader_").append(tableId).append("_").append(table[i]);
            sql.append(" like book_reader ");
            sqlList.add(sql.toString());
        }
        sysRuleDao.doExecuteBatch(sqlList);
    }

    /**
     * 根据ID 获取数据
     * @param ruleId 参数
     * 增加缓存入redis key：ruleId
     * @return {@link SysRule}
     */
    @Override
    @Cacheable(cacheNames  = "system:sysRule" ,key = "#ruleId")
    public SysRule getSysRuleById(String ruleId) {
        SysRule rule =  new SysRule();
        rule.setRuleId(ruleId);
        Example<SysRule> example = Example.of(rule);
        SysRule sysRule = sysRuleDao.findOne(example).orElse(null);
        return sysRule;
    }

    /**
     * 系统规则字段数据
     * @return {@link JSONArray}
     */
    @Override
    @Cacheable(cacheNames  = "system:sysRule", key = "'sysRule'")
    public JSONArray getSysRule() {
        JSONArray rs = new JSONArray();
        SysRule rule = new SysRule ();
        ExampleMatcher matcher = ExampleMatcher.matching()
                .withMatcher("isStop",match -> match.exact());
        Example<SysRule> example = Example.of(rule);
        List<SysRule> sysRuleList = sysRuleDao.findAll(example);
        if(sysRuleList.size()>0){
            rs = JSONArray.of(sysRuleList).getJSONArray(0);
        }
        return rs;
    }
}
